package com.browser.network;

import lombok.Data;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.concurrent.*;
import java.util.Map;
import java.util.zip.GZIPInputStream;

@Data
public class NetworkManager {
    private static final Logger logger = LoggerFactory.getLogger(NetworkManager.class);
    private final ExecutorService executor;
    private final Map<String, HttpURLConnection> connectionPool;
    private final int maxConnections = 10;

    public NetworkManager() {
        this.executor = new ThreadPoolExecutor(
            5, 10,
            60L, TimeUnit.SECONDS,
            new ArrayBlockingQueue<>(100),
            new ThreadPoolExecutor.CallerRunsPolicy()
        );
        this.connectionPool = new ConcurrentHashMap<>();
    }

    public CompletableFuture<String> fetchContent(String urlString) {
        return CompletableFuture.supplyAsync(() -> {
            HttpURLConnection conn = null;
            try {
                conn = connectionPool.get(urlString);
                if (conn == null) {
                    conn = createConnection(urlString);
                }

                conn.setRequestMethod("GET");
                conn.setRequestProperty("User-Agent", "Mozilla/5.0 Simple-Browser/1.0");
                conn.setConnectTimeout(5000);
                conn.setReadTimeout(5000);
                conn.setUseCaches(true);
                conn.setDefaultUseCaches(true);
                
                // 添加常用请求头
                conn.setRequestProperty("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
                conn.setRequestProperty("Accept-Encoding", "gzip, deflate");
                conn.setRequestProperty("Accept-Charset", "UTF-8");
                conn.setRequestProperty("Connection", "keep-alive");

                if (conn.getResponseCode() != 200) {
                    throw new IOException("HTTP error code: " + conn.getResponseCode());
                }

                // 获取响应编码
                String charset = getCharset(conn);
                
                // 处理GZIP压缩
                InputStream inputStream = "gzip".equals(conn.getContentEncoding()) 
                    ? new GZIPInputStream(conn.getInputStream()) 
                    : conn.getInputStream();

                // 读取响应内容
                try (BufferedReader reader = new BufferedReader(
                        new InputStreamReader(inputStream, charset))) {
                    StringBuilder response = new StringBuilder();
                    String line;
                    while ((line = reader.readLine()) != null) {
                        response.append(line).append("\n");
                    }
                    return response.toString();
                }
            } catch (Exception e) {
                logger.error("Failed to fetch content from: {}", urlString, e);
                throw new RuntimeException("Failed to fetch content", e);
            } finally {
                if (conn != null) {
                    if (connectionPool.size() < maxConnections) {
                        connectionPool.put(urlString, conn);
                    } else {
                        conn.disconnect();
                    }
                }
            }
        }, executor);
    }

    private String getCharset(HttpURLConnection conn) {
        String contentType = conn.getContentType();
        if (contentType != null) {
            String[] values = contentType.split(";");
            for (String value : values) {
                value = value.trim();
                if (value.toLowerCase().startsWith("charset=")) {
                    return value.substring("charset=".length());
                }
            }
        }
        // 默认使用UTF-8
        return "UTF-8";
    }

    private HttpURLConnection createConnection(String urlString) throws IOException {
        URL url = new URL(urlString);
        return (HttpURLConnection) url.openConnection();
    }

    public void shutdown() {
        executor.shutdown();
        connectionPool.values().forEach(HttpURLConnection::disconnect);
        connectionPool.clear();
    }
} 